package com.aispeech.asr.apis.ssc.service;

import com.aispeech.asr.apis.ssc.beans.SpeakerSegmentationClustering;
import com.aispeech.asr.apis.ssc.beans.Vad;
import com.aispeech.asr.apis.ssc.config.AppConfig;
import com.aispeech.asr.apis.ssc.data.domain.Align;
import com.aispeech.asr.apis.ssc.data.domain.SscContext;
import com.aispeech.asr.apis.ssc.data.domain.SscResult;
import com.aispeech.asr.apis.ssc.data.form.SscForm;
import com.aispeech.asr.apis.ssc.data.vo.SscData;
import com.aispeech.asr.apis.ssc.data.vo.SscRow;
import com.aispeech.asr.comm.data.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SscService {
    @Autowired
    ApplicationContext applicationContext;
    @Autowired
    AppConfig config;

    public Mono<Result> process(String sessionId, SscForm form, File audioFile) throws IOException {
        SscContext context = SscContext.of(
                sessionId,
                form,
                audioFile
        );

//        Vad vad = applicationContext.getBean(Vad.class);
        SpeakerSegmentationClustering ssc = applicationContext.getBean(SpeakerSegmentationClustering.class);

//        Scheduler scheduler = Schedulers.boundedElastic();

        return Mono.just(context)                      // 1.初始化context，整个流程中随时可用
//                .publishOn(scheduler)           // 2.在独立线程中做音频切割的逻辑，避免锁netty线程
//                .map(vad)                       // 3.音频解码和VAD切割
                .map(ssc)                       // 4.说话人聚类
//                .doOnError(throwable -> {
//                    int errid = ErrorCode.ERR_UNKNOWN.errid;
//                    SscData sscData = new SscData(context.getSessionId(), context.getForm());
//
//                    if (throwable instanceof AsrException) {
//                        AsrException exception = (AsrException) throwable;
//                        errid = exception.getCode();
////                        exception.setData(sscData);
//                    }
//
//                    context.addMetric("finished");
////                    addPrometheusMetrics(asrContext, errid, 0L);
//                    sscData.setMetrics(context.getMetrics());
//                })
                .map(sscContext -> {
                    SscData sscData = new SscData(context.getSessionId(), context.getForm());
                    List<SscRow> sscRowArrayList = new ArrayList<>();
                    SscResult sscResult = sscContext.getSscResult();

                    if (sscResult != null && sscResult.getAligns().size() > 0) {
                        for (Align align : sscResult.getAligns()) {
                            sscRowArrayList.add(SscRow.of(align.getStart(), align.getEnd(), String.valueOf(align.getUid())));
                        }
                    }

                    sscData.setResult(sscRowArrayList);
                    Result result = Result.ok(sscData);

                    context.addMetric("finished");
                    sscData.setMetrics(context.getMetrics());

                    log.info("[ Finish ]productId: {}, sessionId: {}, rows: {}",
                            form.getProductId(), context.getSessionId(), sscData.getResult().size());

                    return result;            // 8.返回最终结果
                });
    }
}
